﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using 配置驾驶舱.Properties;

namespace 配置驾驶舱
{
    public partial class Form1 : Form
    {
        #region //===字段===
        private StatusData statusData = new StatusData();
        private IndicateData indicateData = new IndicateData();
        private ConfigData configData = new ConfigData();
        private EndPoint endPoint = null;
        private IPEndPoint aim_ip;
        #endregion

        #region //=============右击菜单===========
        //当您处理菜单项时，sender 对象指向项目触发的事件。要找出弹出上下文菜单的控件，有2种方法:
        //方法1: 您可以轻松控制从 ContextMenuStrip 的 Opened 处理程序触发的菜单;
        //方法2: 您应该做三件事:
        //1.找到根项。很可能，被点击的项目是另一个项目或更深层次的子项目。
        //2.您应该从根项目中找到 ContextMenuStrip 对象
        //3.很容易从ContextMenuStrip的SourceControl属性中找出有趣的控件
        private void contextMenuStrip更新模拟值_Opened(object sender, EventArgs e)
        {
            contextMenuStrip更新模拟值.Tag = (sender as ContextMenuStrip).SourceControl;
            if (contextMenuStrip更新模拟值.Tag is NumericUpDown)
            {
                ToolStripMenuItem采集.Checked = ToolStripMenuItem结束.Checked = false;
                var obj = contextMenuStrip更新模拟值.Tag as NumericUpDown;
                if (radioButton模拟量.Checked == true)
                {
                    ToolStripMenuItem采集.Text = obj.Tag.Equals("0") ? "采集模拟量最小值" : "采集模拟量最大值";
                    ToolStripMenuItem结束.Text = "元码显示";
                }
                else
                {
                    ToolStripMenuItem采集.Text = "采集档位值, 控制" + (numericUpDown档位序号.Value + Convert.ToInt32(obj.Tag)) + "位档位";
                    ToolStripMenuItem结束.Text = "不使用该位";
                }
            }
        }
        //方法2
        /// <summary>
        /// Gets controls for context menu
        /// </summary>
        /// <param name="Sender">Sender object from menu event handler</param>
        /// <returns></returns>
        private object GetSourceControl(Object Sender)
        {
            // ContextMenuStrip sended?
            if (Sender as ContextMenuStrip != null)
            {
                ContextMenuStrip cms = Sender as ContextMenuStrip;
                return cms.SourceControl;
            }

            var item = Sender as ToolStripItem;

            // move to root item
            while (item.OwnerItem != null)
            {
                item = item.OwnerItem;
            }

            // we have root item now, so lets take ContextMenuStrip object
            var menuObject = item.Owner as ContextMenuStrip;

            if (menuObject != null)
            {
                return menuObject.SourceControl;
            }

            return null;
        }

        private void ToolStripMenuItem采集_Click(object sender, EventArgs e)
        {
            //方法1
            var obj = contextMenuStrip更新模拟值.Tag as NumericUpDown;
            //方法2
            //var obj = GetSourceControl(sender) as TabPage;
            int i = Convert.ToInt32(obj.Tag);
            i += configData.ch * 10;
            CommandFrame commandFrame = new CommandFrame()
            {
                sync = 0x55,
                frame_type = (byte)eFrameType.SET_ANALOG_TAP_Fr,
                link_no = (byte)(configData.MaxLinkCount - 1 - toolStripComboBox连接号.SelectedIndex),
                para = (byte)i,
                para1 = 0
            };
            Send(commandFrame);
        }

        private void ToolStripMenuItem结束_Click(object sender, EventArgs e)
        {
            //方法1
            var obj = contextMenuStrip更新模拟值.Tag as NumericUpDown;
            //方法2
            //var obj = GetSourceControl(sender) as TabPage;
            obj.Value = 0xFFFF;
            int i = Convert.ToInt32(obj.Tag);
            i += configData.ch * 10;
            CommandFrame commandFrame = new CommandFrame()
            {
                sync = 0x55,
                frame_type = (byte)eFrameType.SET_ANALOG_TAP_Fr,
                link_no = (byte)(configData.MaxLinkCount - 1 - toolStripComboBox连接号.SelectedIndex),
                para = (byte)i,
                para1 = 0xFFFF
            };
            Send(commandFrame);
        }

        private void contextMenuStrip校准R_Opened(object sender, EventArgs e)
        {
            contextMenuStrip校准R.Tag = (sender as ContextMenuStrip).SourceControl;
            var obj = contextMenuStrip校准R.Tag as CheckBox;
            if (!obj.Checked)
            {
                contextMenuStrip校准R.Enabled = false;
                return;
            }
            contextMenuStrip校准R.Enabled = true;
            
            if (indicateData.AnalogCode == 0)
            {
                规格化控制ToolStripMenuItem.Checked = true;
                校准控制模式ToolStripMenuItem.Checked = false;
            }
            else
            {
                规格化控制ToolStripMenuItem.Checked = false;
                校准控制模式ToolStripMenuItem.Checked = true;
            }
        }
        private void 校准电阻ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var obj = contextMenuStrip校准R.Tag as CheckBox;
            int Ri = Convert.ToByte(obj.Tag);
            byte i;
            UInt16 analog;
            if (Ri == 0)
            {
                i = configData.输出模拟序号0;
                analog = 1000;
            }
            else if (Ri == 1)
            {
                i = configData.电阻1模拟序号;
                analog = 1000;
            }
            else
            {
                i = configData.电阻2模拟序号;
                analog = 0;
            }
            indicateData.SetAnalog(i, analog);
            Send(indicateData.GetIndicateFrame());
        }
        private void toolStripTextBox0档值_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r')
            {
                var obj = sender as ToolStripTextBox;
                var Robj = contextMenuStrip校准R.Tag as CheckBox;
                int Ri = Convert.ToByte(Robj.Tag) * 10; //cal_pct[]和cal_out的索引
                int pct; //百分比
                switch (obj.Name)
                {
                    case "toolStripTextBox0档值":
                        pct = 0;
                        break;
                    case "toolStripTextBox1档值":
                        pct = (Convert.ToInt32(toolStripTextBox1档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 1;
                        break;
                    case "toolStripTextBox2档值":
                        pct = (Convert.ToInt32(toolStripTextBox2档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 2;
                        break;
                    case "toolStripTextBox3档值":
                        pct = (Convert.ToInt32(toolStripTextBox3档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 3;
                        break;
                    case "toolStripTextBox4档值":
                        pct = (Convert.ToInt32(toolStripTextBox4档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 4;
                        break;
                    case "toolStripTextBox5档值":
                        pct = (Convert.ToInt32(toolStripTextBox5档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 5;
                        break;
                    case "toolStripTextBox6档值":
                        pct = (Convert.ToInt32(toolStripTextBox6档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 6;
                        break;
                    case "toolStripTextBox7档值":
                        pct = (Convert.ToInt32(toolStripTextBox7档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 7;
                        break;
                    case "toolStripTextBox8档值":
                        pct = (Convert.ToInt32(toolStripTextBox8档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 8;
                        break;
                    case "toolStripTextBox9档值":
                        pct = (Convert.ToInt32(toolStripTextBox9档值.Text) - Convert.ToInt32(toolStripTextBox0档值.Text)) * 1000
                            / (Convert.ToInt32(toolStripTextBox数值max.Text) - Convert.ToInt32(toolStripTextBox0档值.Text));
                        Ri += 9;
                        break;
                    default:
                        校准控制模式ToolStripMenuItem_Click(null, null);
                        return;
                }
                CommandFrame commandFrame = new CommandFrame()
                {
                    sync = 0x55,
                    frame_type = (byte)eFrameType.CAL_NONL_R_Fr,
                    link_no = (byte)(configData.MaxLinkCount - 1 - toolStripComboBox连接号.SelectedIndex),
                    para = (byte)Ri,
                    para1 = (ushort)pct
                };
                Send(commandFrame);
            }
        }
        private void 规格化控制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            indicateData.AnalogCode = 0;
            规格化控制ToolStripMenuItem.Checked = true;
            校准控制模式ToolStripMenuItem.Checked = false;
            校准电阻ToolStripMenuItem.Visible = false;
            表最大数值ToolStripMenuItem.Visible = false;
            表0档ToolStripMenuItem.Visible = false;
            表1档ToolStripMenuItem.Visible = false;
            表2档ToolStripMenuItem.Visible = false;
            表3档ToolStripMenuItem.Visible = false;
            表4档ToolStripMenuItem.Visible = false;
            表5档ToolStripMenuItem.Visible = false;
            表6档ToolStripMenuItem.Visible = false;
            表7档ToolStripMenuItem.Visible = false;
            表8档ToolStripMenuItem.Visible = false;
            表9档ToolStripMenuItem.Visible = false;
        }
        private void 校准控制模式ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            indicateData.AnalogCode = 1;
            规格化控制ToolStripMenuItem.Checked = false;
            校准控制模式ToolStripMenuItem.Checked = true;
            校准电阻ToolStripMenuItem.Visible = 
            表最大数值ToolStripMenuItem.Visible = true;
            bool bl = (toolStripTextBox数值max.Text == "") ? false : true;
            表0档ToolStripMenuItem.Visible = 
            表1档ToolStripMenuItem.Visible = 
            表2档ToolStripMenuItem.Visible = 
            表3档ToolStripMenuItem.Visible = 
            表4档ToolStripMenuItem.Visible = 
            表5档ToolStripMenuItem.Visible = 
            表6档ToolStripMenuItem.Visible = 
            表7档ToolStripMenuItem.Visible = 
            表8档ToolStripMenuItem.Visible = 
            表9档ToolStripMenuItem.Visible = bl;
        }
        #endregion

        #region //==============事件=============
        private void socketCom1_OnDataReceived(object sender, SocketCommunication.SocketEventArgs e)
        {
            if (endPoint == null)
            {
                endPoint = e.State.endPoint;
                timer网断开.Enabled = true;
                groupBox输入状态.Enabled = true;
                groupBox配置终端机.Enabled = true;
            }
            else
            {
                timer网断开.Stop();
                timer网断开.Interval = 100;
                timer网断开.Start();
            }
            //解码
            byte[] buf = e.State.buffer;
            switch ((eFrameType)buf[ConfigFrame.ftOffset])
            {
                case eFrameType.LINK_Fr:
                    break;
                case eFrameType.LINK_AFFIRM_Fr:
                    break;
                case eFrameType.STATUS_Fr:
                    statusData.Update(buf);

                    break;
                case eFrameType.INDICAT_Fr:
                    break;
                case eFrameType.UP_CONFIG_Fr:
                    configData.Update(buf);
                    UpdateToolStripComboBox连接号();
                    groupBox配置输出指示.Enabled = groupBox配置输入开关量.Enabled = groupBox配置输入模拟量.Enabled = true;
                    break;
                case eFrameType.DN_CONFIG_Fr:
                    break;
                case eFrameType.GET_CONFIG_Fr:
                    break;
                case eFrameType.SAVE_CONFIG_Fr:
                    break;
                default:
                    break;
            }
        }

        private void timer网断开_Tick(object sender, EventArgs e)
        {
            endPoint = null;
            timer网断开.Stop();
            timer网断开.Enabled = false;
            groupBox输入状态.Enabled = false;
            groupBox配置终端机.Enabled = false;
            groupBox配置输出指示.Enabled = groupBox配置输入开关量.Enabled = groupBox配置输入模拟量.Enabled = false;
        }
        #endregion

        #region //===进入和退出===
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            configData.终端IP = Settings.Default.目标IP;
            configData.远端IP = Settings.Default.本地IP;
            configData.终端端口 = (ushort)Settings.Default.终端Port;
            configData.远端端口 = (ushort)Settings.Default.本机Port;
            toolStripComboBox设备名称.Items.AddRange(Enum.GetNames(typeof(eDeviceId)));
            statusDataBindingSource.DataSource = statusData;
            indicateDataBindingSource.DataSource = indicateData;
            configDataBindingSource.DataSource = configData;

            socketCom1.Start();
            aim_ip = new IPEndPoint(socketCom1.目标IPAddress, socketCom1.目标Port);
            //trackBar1_MouseUp(null, null); //发送指示帧
            UpdateToolStripComboBox连接号(); //初始化配置界面
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
        }
        #endregion

        #region //===方法===
        private void Send(object structObj)
        {
            if (endPoint != null)
                socketCom1.Send(structObj, endPoint);
            else
                socketCom1.Send(structObj, aim_ip);
        }
        private void toolStripComboBox设备名称_TextChanged(object sender, EventArgs e)
        {
            configData.设备名称 = toolStripComboBox设备名称.Text;
        }
        private void toolStripComboBox连接号_SelectedIndexChanged(object sender, EventArgs e)
        {
            toolStripButton刷新配置_Click(null, null);
        }
        private void UpdateToolStripComboBox连接号()
        {
            while (toolStripComboBox连接号.Items.Count > configData.MaxLinkCount)
                toolStripComboBox连接号.Items.RemoveAt(toolStripComboBox连接号.Items.Count - 1);
            while (toolStripComboBox连接号.Items.Count < configData.MaxLinkCount)
                toolStripComboBox连接号.Items.Add(toolStripComboBox连接号.Items.Count.ToString());
            //toolStripComboBox连接号.Text = configData.NowLinkNo.ToString();
            toolStripComboBox连接号.SelectedIndex = configData.NowLinkNo;

            toolStripComboBox设备名称.Text = configData.设备名称;
            toolStripLabelHW_Ver.Text = configData.固件版本;
        }

        private void toolStripButton刷新配置_Click(object sender, EventArgs e)
        {
            CommandFrame getConfigFrame = new CommandFrame()
            {
                sync = 0x55,
                frame_type = (byte)eFrameType.GET_CONFIG_Fr,
                link_no = (byte)(configData.MaxLinkCount - 1 - toolStripComboBox连接号.SelectedIndex)
            };
            Send(getConfigFrame);
            toolStripButton刷新配置.Checked = true;
            toolStripButton更新配置.Checked = false;
            toolStripButton保存配置.Checked = false;
            toolStripButton复位.Checked = false;
        }
        private void toolStripButton保存配置_Click(object sender, EventArgs e)
        {
            CommandFrame getConfigFrame = new CommandFrame()
            {
                sync = 0x55,
                frame_type = (byte)eFrameType.SAVE_CONFIG_Fr,
                link_no = (byte)(configData.MaxLinkCount - 1 - toolStripComboBox连接号.SelectedIndex)
            };
            Send(getConfigFrame);
            if (Settings.Default.目标IP != configData.终端IP || Settings.Default.本地IP != configData.远端IP ||
                Settings.Default.终端Port != configData.终端端口 || Settings.Default.本机Port != configData.远端端口)
            {
                Settings.Default.目标IP = configData.终端IP;
                Settings.Default.本地IP = configData.远端IP;
                Settings.Default.终端Port = configData.终端端口;
                Settings.Default.本机Port = configData.远端端口;
                Settings.Default.Save();
            }
            toolStripButton刷新配置.Checked = false;
            toolStripButton更新配置.Checked = false;
            toolStripButton保存配置.Checked = true;
            toolStripButton复位.Checked = false;
        }
        private void toolStripButton复位_Click(object sender, EventArgs e)
        {
            CommandFrame resetFrame = new CommandFrame()
            {
                sync = 0x55,
                frame_type = (byte)eFrameType.RESET_Fr,
            };
            Send(resetFrame);
            toolStripButton刷新配置.Checked = false;
            toolStripButton更新配置.Checked = false;
            toolStripButton保存配置.Checked = false;
            toolStripButton复位.Checked = true;
        }
        private void toolStripButton更新配置_Click(object sender, EventArgs e)
        {
            Send(configData.GetConfigFrame());
            toolStripButton刷新配置.Checked = false;
            toolStripButton更新配置.Checked = true;
            toolStripButton保存配置.Checked = false;
            toolStripButton复位.Checked = false;
        }

        private void numericUpDown输出max_ValueChanged(object sender, EventArgs e)
        {
            if (numericUpDown输出max.Enabled)
                timer延时发送.Enabled = true;
        }      
        private void timer延时发送_Tick(object sender, EventArgs e)
        {
            timer延时发送.Enabled = false;
            Send(configData.GetConfigFrame());
            toolStripButton刷新配置.Checked = false;
            toolStripButton更新配置.Checked = true;
            toolStripButton保存配置.Checked = false;
            toolStripButton复位.Checked = false;
        }

        private void numericUpDown模拟0_ValueChanged(object sender, EventArgs e)
        {
            timer发送输出.Enabled = true;
        }
        private void timer发送输出_Tick(object sender, EventArgs e)
        {
            timer发送输出.Enabled = false;
            Send(indicateData.GetIndicateFrame());
        }
        private void trackBar1_MouseUp(object sender, MouseEventArgs e)
        {
            Send(indicateData.GetIndicateFrame());
        }
        #endregion

        private void textBoxMAC0_KeyPress(object sender, KeyPressEventArgs e)
        {
            //0-9,a-f,A-F,后退键backspace可输入
            if ((e.KeyChar >= '0' && e.KeyChar <= '9') /*|| (e.KeyChar >= 'a' && e.KeyChar <= 'f')*/ ||
                (e.KeyChar >= 'A' && e.KeyChar <= 'F') || (e.KeyChar == '\b'))
            {
                //if (e.KeyChar >= 'a' && e.KeyChar <= 'f') e.KeyChar = Convert.ToChar(e.KeyChar.ToString().ToUpper()); //小写变大写
                //--通过设置textBox的属性CharacterCasing=Upper解决!!
                e.Handled = false;
            }
            else e.Handled = true; //其它输入拒绝处理
        }

        private void maskedTextBoxIP_KeyDown(object sender, KeyEventArgs e)
        {
            var obj = sender as MaskedTextBox;
            //当输入点(.)的时候，自动跳至下一字段
            if (e.KeyCode == Keys.Decimal || e.KeyCode == Keys.OemPeriod) //Decimal为数字键盘的小数点'.del',OemPeriod为句号'>.'
            {
                switch (obj.SelectionStart) //000.000.000.000
                {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                        obj.SelectionStart = 4;
                        break;
                    case 4:
                    case 5:
                    case 6:
                    case 7:
                        obj.SelectionStart = 8;
                        break;
                    case 8:
                    case 9:
                    case 10:
                    case 11:
                        obj.SelectionStart = 12;
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
